import Taro from '@tarojs/taro';

import { applyFormKey } from '../config';
import { default as ApplyUtils } from '../utils/apply'

/**
 * 处理产品数据的公共逻辑工具类
 */
class Product {
    /**
     * 根据值匹配对应的选项对象
     * @param {String} value 要匹配的值
     * @param {Array} options 选项数组
     */
    getOptionnByValue(value: string | number, options: Array<any>): string | number {
        return options.find(item => item.value === value)
    }

    /**
     * 转换额度为字符串
     * @param {number} minDeposit 最小额度
     * @param {number} maxDeposit 最大额度
     */
    convertDepositRangeToDisplayStr(minDeposit: number, maxDeposit: number): string {
        let result = `${minDeposit}-${maxDeposit}`

        if (minDeposit >= 10000 && maxDeposit >= 10000) {
            const minDepositStr = parseFloat((minDeposit / 10000).toFixed(2))
            const maxDepositStr = parseFloat((maxDeposit / 10000).toFixed(2))

            result = `${minDepositStr}-${maxDepositStr}万`
        }
        return result
    }

    /**
     * 转换月综合费率为字符串
     * @param {number} combination_rate_type    费率类型
     * @param {string} combination_rate         月综合费率(%)
     */
    converCombinationRateTypeToDisplayStr(combination_rate_type: number, combination_rate: string): string {
        let result = combination_rate
        if (combination_rate_type === 1) {
            if (typeof combination_rate === 'string') {
                var rateArr = combination_rate.split('-')
                if (rateArr.length === 2) {
                    result = rateArr[0] + '%-' + rateArr[1] + '%'
                }
            }
        } else if (combination_rate_type === 2) {
            result = '面议'
        } else if (combination_rate_type === 3) {
            result = '无此费用'
        } else if (combination_rate_type === 4) {
            result = this.converPercentToString(combination_rate, 100)
        }
        return result
    }

    /**
     * 转换百分比为字符串
     * @param {number} percent
     * @param {number} times    放大倍数
     */
    converPercentToString(percent, times) {
        let result = parseInt(percent)

        if (result > 0 && times > 0) {
            result = parseFloat((percent / times).toFixed(2))
        }
        return result + '%'
    }

    /**
     * 转换放款天数
     * @param {string} loan_time  放款天数字符串
     * @param {number} loan_time_type 放款天数类型
     */
    converLoanTimeToDisplayStr(loan_time: string, loan_time_type: number) {
        let result = loan_time
        if (typeof loan_time === 'string') {
            if (loan_time_type === 1) {
                if (loan_time.split('-').length === 2) {
                    result = loan_time + '天放款'
                }
            } else if (loan_time_type === 2) {
                result = loan_time + '天以上放款'
            } else if (loan_time_type === 3) {
                result = '当天放款'
            }
        }
        return result
    }

    /**
     * 把产品类型转换为字符串
     * @param {number} type 产品类型
     */
    convertProductTypeToString(type: number): string {
        let result = ''
        switch (type) {
            case 1:
                result = '工薪贷'
                break
            case 2:
                result = '生意贷'
                break
            case 3:
                result = '车抵贷'
                break
            case 4:
                result = '房抵贷'
                break
            default:
                break
        }
        return result
    }

    /**
     * 把字段转换为查询条件
     * @param {*} condition 
     */
    convertToQueryCondition(condition: any = {
        deposit: ''
    }) {
        const {
            deposit,
            time_limit,
            sort,
            product_type,
            mortgage_type,
            page,
            page_size,
        } = condition

        const result: any = {}

        // 贷款额度
        if (deposit) {
            result.price = deposit
        }
        // 贷款期限
        if (time_limit) {
            result.limit_time = time_limit
        }
        // 排序方式
        if (sort) {
            switch (sort) {
                case 1:
                    // 智能排序
                    break
                case 2:
                    // 易通过
                    result.easy_pass = 1
                    break
                case 3:
                    // 利息最少
                    result.rate = 1
                    break
                case 4:
                    // 放款最快
                    result.fast = 1
                    break
                case 5:
                    // 热门
                    result.hot = 1
                    break
                default:
                    break
            }
        }
        // 产品类型
        if (product_type) {
            result.product_type = product_type
        }
        // 抵押类型
        if (mortgage_type) {
            result.mortgage_type = mortgage_type
        }
        if (page) {
            result.page = page
        }
        if (page_size) {
            result.page_size = page_size
        }

        return result
    }

    /**
     * 把金额数字转换为带千分位的字符串
     * @param amount 金额
     */
    toThousand(amount: number): string {
        if (amount > 0) {
            const result: Array<string> = []
            let counter: number = 0
            const num: Array<string> = (amount || 0).toString().split('')
            for (let i = num.length - 1; i >= 0; i--) {
                counter++
                result.unshift(num[i])
                if (!(counter % 3) && i !== 0) {
                    result.unshift(',')
                }
            }
            return result.join('')
        } else {
            return ''
        }
    }

    /**
     * 从本地storage中获取已保存的申请表单对象
     */
    getApplyFormFromStorage(): any {
        const applyForm = Taro.getStorageSync(applyFormKey)
        return applyForm
    }

    /**
     * 保存申请表单对象到本地storage
     */
    saveApplyFormToStorage(form) {

        const formCopy = Object.assign({}, form)
        // 不保存贷款额度,期限,产品id
        delete formCopy.loan_limit
        delete formCopy.loan_date_limit
        delete formCopy.product_id

        // 合并新的和旧的表单对象
        const old = this.getApplyFormFromStorage()
        let update = formCopy
        if (old) {
            update = Object.assign(old, update)
        }

        Taro.setStorageSync(applyFormKey, update)
    }

    /**
     * 初始化年龄选项
     * 根据 minAge 与 maxAge 计算年龄选项
     * @param {number} minAge   最小年龄
     * @param {number} maxAge   最大年龄
     */
    initAgeOptions(minAge: number = 18, maxAge: number = 70): number[] {
        const result: number[] = []
        for (let i = 0; i <= maxAge - minAge; i++) {
            result.push(minAge + i)
        }
        return result
    }

    /**
     * 获取产品的类型 
     * 返回值 
     * 1: 快速产品 
     * 2: 银行产品
     * @param {any} product 产品对象
     */
    getProductLoanType(product: any): number {
        let result = 1
        if (product.product_type) {
            // product_type字段存在，表示银行产品
            result = 2
        }
        return result
    }

    /**
     * 检查产品是否已申请过
     * @param {*} product 产品对象
     */
    checkIsApplyProduct(product: any): boolean {
        // 检查产品是否已申请
        let result = false
        const applyUtils = new ApplyUtils()

        if (product) {
            const applyProducts = applyUtils.getOrderFromLocalStorage()

            if (Array.isArray(applyProducts) && applyProducts.length > 0) {
                for (const item of applyProducts) {
                    const { product_id } = product
                    const loanType = this.getProductLoanType(product)

                    if (product_id === item.product_id && loanType === item.loan_type) {
                        result = true
                        break
                    }
                }
            }
        }

        return result
    }

    /**
     * 根据产品计算贷款期限选项
     * @param {*} product   产品对象
     */
    getTimeLimitOptions(product): number[] {
        const result: number[] = []
        if (product) {
            const {
                min_time_limit,
                max_time_limit
            } = product

            for (let i = 0, len = max_time_limit - min_time_limit + 1; i < len; i++) {
                result.push(min_time_limit + i)
            }
        }
        return result
    }

    /**
     * 根据产品计算贷款选项并返回选项对象数组
     * @param product 
     */
    getTimeLimitObjOptions(product): any[] {
        let options: any = this.getTimeLimitOptions(product)
        options = options.map(item => {
            return {
                name: `${item}个月`,
                value: item,
            }
        })
        return options
    }

    /**
     * 计算利息
     * @param {Number} money 贷款额
     * @param {Number} time 贷款期限
     * @param {*} product 产品对象
     */
    caculatInterest(money: number, time: number, product: any): string | number {
        let result: string | number = '0'

        if (money > 0 && product) {

            const {
                combination_rate_type,
                combination_rate
            } = product

            // 当 combination_rate_type = 1 时才计算, 此时 combination_rate 是个范围， 例子: '1.20-2.30'
            if (combination_rate_type === 1) {
                if (typeof combination_rate === 'string') {
                    const combinationRateArr = combination_rate.split('-')

                    // combinationRateArr.length = 2 时继续处理
                    if (combinationRateArr.length === 2) {
                        let maxCombinationRate: number | string = combinationRateArr[1]
                        // maxCombinationRate 例子： '1.20',表示 1.2%
                        maxCombinationRate = parseFloat(maxCombinationRate)
                        // 计算利息
                        const interest = maxCombinationRate / 100 * money * time
                        result = parseFloat(interest.toFixed(0))
                    } else {
                        const combinationRateNumber = parseFloat(combination_rate)
                        // 计算利息, combination_rate 放大100倍后保存，所以要先除 100
                        const interest = combinationRateNumber / 100 / 100 * money * time
                        result = parseFloat(interest.toFixed(0))
                    }
                } else if (combination_rate_type === 4) {
                    // 计算利息, combination_rate 放大100倍后保存，所以要先除 100
                    const interest = parseInt(combination_rate) / 100 / 100 * money * time
                    result = parseFloat(interest.toFixed(0)) + ''
                }
            } else if (combination_rate_type === 2) {
                result = '面议'
            } else if (combination_rate_type === 3) {
                result = '无此费用'
            }
        }
        return result
    }

    /**
     * 计算利息并转换为显示的字符串
     * @param money 贷款额度
     * @param time 贷款期限
     * @param product 产品对象
     */
    convertToInterestStr(money: number, time: number, product: any): string {
        const interest = this.caculatInterest(money, time, product)

        if (typeof interest === 'number') {
            return `${this.toThousand(interest)}元`
        } else {
            return interest
        }
    }

    /**
     * 计算一次性费用
     * @param money 贷款额
     * @param product 产品对象
     */
    caculatNonrecurringExpense(money: number, product: any): number | string {
        let result: number | string = 0

        if (money > 0 && product) {
            const {
                disposable_cost_type,
                disposable_cost
            } = product

            // disposable_cost_type = 1 表示一次性费用是个百分比范围，可以计算
            if (disposable_cost_type === 1) {

                if (typeof disposable_cost === 'string') {
                    const disposableCostArr = disposable_cost.split('-')
                    if (disposableCostArr.length === 2) {
                        const minCost: number = parseFloat(disposableCostArr[0])
                        const maxCost: number = parseFloat(disposableCostArr[1])

                        result = money * maxCost / 100
                    } else {
                        // 把字符串转换为数字
                        const disposableCost = parseFloat(disposable_cost)
                        // disposable_cost 放大100倍后存储，所以要除100
                        result = money * disposableCost / 100 / 100
                    }
                }
            } else if (disposable_cost_type === 2) {
                // disposable_cost_type = 2 表示一次性费用面议
                result = '面议'
            } else if (disposable_cost_type === 3) {
                result = '无此费用'
            } else if (disposable_cost_type === 4) {
                // 把字符串转换为数字
                const disposableCost = parseFloat(disposable_cost)
                // disposable_cost 放大100倍后存储，所以要除100
                result = money * disposableCost / 100 / 100
            }
        }
        return result
    }

    /**
     * 转换一次性费用为字符串
     * @param money 额度
     * @param product 产品对象
     */
    convertToNonrecurringExpenseStr(money: number, product: any): string {
        const nonrecurringExpense = this.caculatNonrecurringExpense(money, product)

        if (typeof nonrecurringExpense === 'number') {
            return this.toThousand(nonrecurringExpense) + '元'
        }

        return nonrecurringExpense
    }

    /**
     * 计算担保金
     * @param {Number} money 贷款额
     * @param {*} product 产品对象
     */
    caculatGuaranteeMoney(money, product): number | string {
        let result: number | string = 0

        if (money > 0 && product) {
            const {
                guarantee_type,
                guarantee
            } = product

            // disposable_cost_type = 1 表示一次性费用是个百分比范围，可以计算
            if (guarantee_type === 1) {
                if (typeof guarantee === 'string') {
                    const guaranteeArr = guarantee.split('-')
                    if (guaranteeArr.length === 2) {
                        const minRate = parseFloat(guaranteeArr[0])
                        const maxRate = parseFloat(guaranteeArr[1])

                        result = money * maxRate / 100
                    } else {
                        // 先除100再计算
                        result = money * parseInt(guarantee) / 100 / 100
                    }
                }
            } else if (guarantee_type === 2) {
                // guarantee_type = 2 表示担保金比率面议
                result = '面议'
            } else if (guarantee_type === 3) {
                result = '无此费用'
            } else if (guarantee_type === 4) {
                // 先除100再计算
                result = money * guarantee / 100 / 100
            }
        }
        return result
    }

    /**
     * 计算担保金
     * @param money 贷款额
     * @param product 产品对象
     */
    convertToGuaranteeMoneyStr(money: number, product: any): string {
        const guaranteeMoney = this.caculatGuaranteeMoney(money, product)

        if (typeof guaranteeMoney === 'number') {
            return this.toThousand(guaranteeMoney) + '元'
        }
        return guaranteeMoney
    }

    /**
     * 把钱数转换为万作为单位
     * @param money 
     */
    converToTenThousand(money: number): number {
        let result = money
        if (money >= 10000) {
            // 钱数 >= 10000 的情况下，
            // 把钱数 / 10000 后，保留两位小数
            // result = (money / 10000).toFixed(2)
            result = parseFloat((money / 10000).toFixed(2))
        }
        return result
    }

    /**
     * 把钱数转换为万作为单位的字符串
     * @param money 
     */
    converToTenThousandDisplayStr(money: number): number | string {
        let result: number | string = money
        if (money >= 10000) {
            // 钱数 >= 10000 的情况下，
            // 把钱数 / 10000 后，保留两位小数
            // result = (money / 10000).toFixed(2)
            result = parseFloat((money / 10000).toFixed(2)) + '万元'
        }
        return result
    }

    /**
     * 输入金额校验，小于最小值调整输入到最小值，超过最大值则自动调整到最大值
     * 返回符合范围的额度值
     * @param money 金额
     * @param product 产品对象
     */
    inputDepositeValidate(money: number, product: any): number {
        let result = money
        if (money >= 0 && product) {
            const maxDeposit = product['max_deposit']
            const minDeposit = product['min_deposit']

            let validateVal = money
            if (money > maxDeposit) {
                validateVal = maxDeposit
                Taro.showToast({
                    title: `产品额度范围是${this.converToTenThousandDisplayStr(minDeposit)}-${this.converToTenThousandDisplayStr(maxDeposit)}，已调整到最大额度`,
                    icon: 'none'
                })
            } else if (money < minDeposit) {
                validateVal = minDeposit
                Taro.showToast({
                    title: `产品额度范围是${this.converToTenThousandDisplayStr(minDeposit)}-${this.converToTenThousandDisplayStr(maxDeposit)}，已调整到最小额度`,
                    icon: 'none'
                })
            }
            result = validateVal
        }
        return result
    }

    /**
     * 处理收藏产品数据，返回当前产品的收藏id
     * @param collections
     * @param product
     */
    getCollectionId(collections: any[], product: any): string {
        let result = ''
        if (Array.isArray(collections)) {
            for (const item of collections) {
                const { collection_id, product_id, loan_type } = item
                const curProductId = product.product_id
                const curLoanType = this.getProductLoanType(product)

                if (product_id === curProductId && loan_type === curLoanType) {
                    result = collection_id
                    break
                }
            }
        }

        return result
    }

    /**
     * 计算产品申请次数
     * @param applyList  申请列表
     * @param product 产品对象
     */
    getProductApplyCount(applyList: any, product: any) {
        // 检查产品是否已申请
        let count = 0

        if (product) {
            const applyProducts = applyList
            if (Array.isArray(applyProducts) && applyProducts.length > 0) {
                for (const item of applyProducts) {
                    const { product_id } = product
                    const loanType = this.getProductLoanType(product)

                    if (product_id === item.product_id && loanType === item.loan_type) {
                        count++
                    }
                }
            }
        }

        return count
    }

    /**
     * 转换金额
     * @param {*} money    金额
     * @param {Boolean} isConvertToTen  是否转换成万元
     */
    converMoneyToDisplay(money: number | string, isConvertToTen?: boolean): string {
        var result: any = money
        if (typeof money === 'number') {
            if (money > 10000 && isConvertToTen) {
                result = this.converToTenThousand(money)
                result += '万'
            } else {
                result += '元'
            }
        }
        return result
    }

    /**
     * 根据借款数量和产品计算还款金额,利息和费用
     * @param money  借款金额
     * @param time 借款期限(月)
     * @param product 产品对象
     */
    caculateRepaymentAndInterestAndFee(money: number, time: number, product: any): {
        repayment: number | string,
        interestAndFee: number | string,
    } {
        let result: {
            repayment: number | string,
            interestAndFee: number | string,
        } = {
            repayment: money,
            interestAndFee: 0,
        }

        if (product) {

            // 转换 money 为 number
            const moenyNumber = typeof money === 'string' ? parseFloat(money) : money
            // 转换 time 为 number
            const timeNumber = typeof time === 'string' ? parseFloat(time): time

            // 计算利息
            const interest = this.caculatInterest(moenyNumber, timeNumber, product)
            // 计算一次性费用
            const nonrecurringExpense = this.caculatNonrecurringExpense(moenyNumber, product)

            if (typeof interest === 'number' && interest >= 0) {
                result.repayment = interest + moenyNumber
            }

            if (typeof nonrecurringExpense === 'number' && nonrecurringExpense >= 0) {
                if (typeof result.repayment === 'number') {
                    // 还款金额是数字才进行计算
                    result.repayment += nonrecurringExpense
                }
            }

            if (result.repayment === money) {
                if (typeof interest === 'string' || typeof nonrecurringExpense === 'string') {
                    result.repayment = '面议'
                }
            }

            if (typeof result.repayment === 'number') {
                // 使用parseFloat 处理 2000.00(小数位都为0)的情况， 转换为 2000
                result.repayment = parseFloat((result.repayment).toFixed(2))

                // 计算利息和费用
                result.interestAndFee = (result.repayment - money).toFixed(2)
                result.interestAndFee = parseFloat(result.interestAndFee + '')

            } else if (typeof result.repayment === 'string') {
                // 还款金额为字符串时， 利息和费用与还款金额字符一致
                result.interestAndFee = result.repayment
            }

        }

        return result
    }

    /**
     * 根据借款数量和产品计算到账金额
     * @param money  借款金额
     * @param time 借款期限(月)
     * @param product 产品对象
     */
    caculateGetMoney(money: number, time: number, product: any): number {
        // 暂时借款数量就是到账金额
        let result = money
        return result
    }

}
export default Product